package com.share.common.logback;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.IThrowableProxy;
import ch.qos.logback.classic.spi.StackTraceElementProxy;
import ch.qos.logback.contrib.mongodb.MongoDBAppenderBase;
import com.mongodb.BasicDBObject;

import java.util.Date;
import java.util.Map;

public class LogToMongoDbAppender extends MongoDBAppenderBase<ILoggingEvent> {

    private boolean includeCallerData;

    @Override
    protected BasicDBObject toMongoDocument(ILoggingEvent event) {
        BasicDBObject logEntry = new BasicDBObject();
        logEntry.append("message", event.getFormattedMessage());
        logEntry.append("logger", event.getLoggerName());
        logEntry.append("thread", event.getThreadName());
        logEntry.append("timestamp", new Date(event.getTimeStamp()));
        logEntry.append("level", event.getLevel().toString());
        logEntry.append("level", event.getLevel().toString());

        Map<String, String> propertyMap = event.getLoggerContextVO().getPropertyMap();
        logEntry.append("ip", propertyMap.get("tmpIp"));
        logEntry.append("serverPort", propertyMap.get("serverPort"));
        logEntry.append("LOG_PATTERN_FORMAT", propertyMap.get("LOG_PATTERN_FORMAT"));


        /*异常信息的提取*/
        if (event.getThrowableProxy() != null) {
            IThrowableProxy throwable = event.getThrowableProxy();
            final BasicDBObject throwableDoc = new BasicDBObject();
            throwableDoc.append("class", throwable.getClassName());
            throwableDoc.append("message", throwable.getMessage());
            throwableDoc.append("stackTrace", toSteArray(throwable));
            if (throwable.getCause() != null) {
                throwableDoc.append("cause", throwable.getCause());
            }

            logEntry.append("throwable", throwableDoc);
        }

        return logEntry;
    }


    private String[] toSteArray(IThrowableProxy throwableProxy) {
        final StackTraceElementProxy[] elementProxies = throwableProxy.getStackTraceElementProxyArray();
        final int totalFrames = elementProxies.length - throwableProxy.getCommonFrames();
        final String[] stackTraceElements = new String[totalFrames];
        for (int i = 0; i < totalFrames; ++i)
            stackTraceElements[i] = elementProxies[i].getStackTraceElement().toString();
        return stackTraceElements;
    }
}
